package com.etong.frame.dispatcher;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.etong.frame.directive.Directive;
import com.etong.frame.directive.DirectiveConfig;
import com.etong.frame.directive.GroupConfig;
import com.etong.frame.directive.GroupDirective;
import com.etong.frame.directive.factory.DirectiveLoader;
import com.etong.frame.directive.factory.DirectiveManager;
import com.etong.frame.directive.util.CommonStatus;
import com.etong.framework.service.JSONRequest;
import com.etong.framework.service.JSONResponse;

public class Dispatcher {
	protected static final Logger logger = LoggerFactory
			.getLogger(Dispatcher.class);

	private static final String KEY_SELECTS = "selects";
	private static final String KEY_COUNT = "count";
	private static final String KEY_DIRECTIVE = "directive";

	private DirectiveManager directiveMgr;

	public Dispatcher() {
		directiveMgr = new DirectiveManager();
	}

	/**
	 * @Title : loadCheckers
	 * @Description : 加载检查器
	 * @params
	 * @param checkerMaps
	 * @return 设定文件
	 * @return boolean 返回类型
	 * @throws
	 */
	public boolean loadCheckers(List<Map<String, Object>> checkerMaps) {
		return directiveMgr.createCheckers(checkerMaps);
	}

	/**
	 * @Title : loadDirectives
	 * @Description : 加载指信
	 * @params
	 * @return 设定文件
	 * @return boolean 返回类型
	 * @throws
	 */
	public boolean loadDirectives(DirectiveLoader loader) {
		return directiveMgr.createDirectives(loader);
	}

	/**
	 * @Title : loadGroups
	 * @Description : 加载指令组
	 * @params
	 * @param groupConfigs
	 * @return 设定文件
	 * @return boolean 返回类型
	 * @throws
	 */
	public boolean loadGroups(List<GroupConfig> groupConfigs) {
		return directiveMgr.createGroupDirectives(groupConfigs);
	}

	/**
	 * @Title : dispatch
	 * @Description : 调度服务
	 * @params
	 * @param dataJson
	 * @return 设定文件
	 * @return JSONResponse 返回类型
	 * @throws
	 */
	public JSONResponse dispatch(JSONRequest dataJson) {
		logger.info("Dispatch directive:" + dataJson);

		JSONResponse res = new JSONResponse();

		String groupName = dataJson.getString(KEY_DIRECTIVE);
		GroupDirective groupDirective = directiveMgr
				.getGroupDirective(groupName);
		if (null == groupDirective) {
			res.error(CommonStatus.DIRECTIVE_NO_FOUND, "No directive named:"
					+ groupName);
			return res;
		}

		// 逐个执行group中的指令
		for (Directive directive : groupDirective.getDirectives()) {
			CommonStatus status = directive.execute(dataJson.toJSONObject());
			if (!status.succeed()) {
				res.error(status.getStatus(), status.getMsg(),
						status.getToast());
				return res;
			}

			DirectiveConfig directiveConfig = (DirectiveConfig) directive;
			Integer outputFormat = directiveConfig.getOutputFormat();
			String outputName = directiveConfig.getOuputName();
			if (directiveConfig.isOutput()) {
				if (Directive.OutputFormat.LIST.equals(outputFormat)) {
					res.appendList(status.getObject(), outputName, KEY_SELECTS);
				} else if (Directive.OutputFormat.INT.equals(outputFormat)) {
					res.appendSize(status.getObject(), outputName, KEY_COUNT);
				} else if (Directive.OutputFormat.ONE.equals(outputFormat)) {
					res.append(status.getObject());
				}
			}

			// 将查询结构输出到下一步操作
			if (directiveConfig.isOutputNext()) {
				if (status.getObject() instanceof Map) {
					dataJson.putAll(status.getObject());
				} else {
					// 使用指令作为key保存执行结果
					dataJson.put(directiveConfig.getName(), status.getObject());
				}
			}
		}

		return res;
	}

	/**
	 * @Title : getGroupDirective
	 * @Description : 获取组指令
	 * @params
	 * @param groupName
	 * @return 设定文件
	 * @return GroupDirective 返回类型
	 * @throws
	 */
	public GroupDirective getGroupDirective(String groupName) {
		return directiveMgr.getGroupDirective(groupName);
	}
}
